package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ik.IkDto;
import com.ruoyi.common.utils.ik.IkUtils;
import com.ruoyi.system.domain.BsSmartKefu;
import com.ruoyi.system.mapper.BsSmartKefuMapper;
import com.ruoyi.system.service.BsSmartKefuService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @ClassName BsSmartKefuServiceImpl
 * @Author kenn
 * @Version 1.0.0
 * @Date 2023年11月27日 11:18:00
 */
@Service
public class BsSmartKefuServiceImpl extends ServiceImpl<BsSmartKefuMapper, BsSmartKefu> implements BsSmartKefuService {

    @Override
    public TableDataInfo<BsSmartKefu> pageList(PageDomain pageDomain) {
        LambdaQueryWrapper<BsSmartKefu> queryWrapper = new LambdaQueryWrapper<>();
        PageHelper.startPage(pageDomain.getPageNum(), pageDomain.getPageSize());
        List<BsSmartKefu> zhusuList = list(queryWrapper);
        PageInfo<BsSmartKefu> pageInfo = new PageInfo<>(zhusuList);
        return new TableDataInfo<>(pageInfo.getList(), pageInfo.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveEntity(BsSmartKefu smartKefu) {
        LambdaQueryWrapper<BsSmartKefu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BsSmartKefu::getSearchKey, smartKefu.getSearchKey());
        int sameNameCount = count(queryWrapper);
        if (sameNameCount > 0) {
            throw new BaseException("关键词已存在");
        }
        return save(smartKefu);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateEntity(BsSmartKefu smartKefu) {
        LambdaQueryWrapper<BsSmartKefu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(BsSmartKefu::getId, smartKefu.getId());
        queryWrapper.eq(BsSmartKefu::getSearchKey, smartKefu.getSearchKey());
        int sameNameCount = count(queryWrapper);
        if (sameNameCount > 0) {
            throw new BaseException("关键词已存在");
        }
        return updateById(smartKefu);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        Assert.notNull(id, "主键id不能为空");
        return removeById(id);
    }

    @Override
    public List<BsSmartKefu> answer(String question) throws IOException {
        List<BsSmartKefu> kefuList = new ArrayList<>();
        if (StringUtils.isEmpty(question)){
            return Collections.emptyList();
        }
        List<IkDto> ikDtos = IkUtils.participle(question, false);
        // 解决部分不可拆解的词语，IK分词器返回空集合的情况
        if (CollUtil.isEmpty(ikDtos)) {
            IkDto ikDto = new IkDto();
            ikDto.setWord(question);
            ikDto.setWeight(question.length());
            ikDtos.add(ikDto);
        }
        LambdaQueryWrapper<BsSmartKefu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(BsSmartKefu::getSearchKey, ikDtos.get(0).getWord());
        for (int i = 1; i < ikDtos.size(); i++) {
            queryWrapper.or().like(BsSmartKefu::getSearchKey, ikDtos.get(i).getWord());
        }
        kefuList = list(queryWrapper);
        for (BsSmartKefu kefu : kefuList) {
            int weight = 1;
            for (IkDto ikDto : ikDtos) {
                if (kefu.getSearchKey().contains(ikDto.getWord())) {
                    weight += ikDto.getWeight();
                }
            }
            kefu.setWeight(weight);
        }
        return kefuList.stream().sorted(Comparator.comparing(BsSmartKefu::getWeight).reversed()).collect(Collectors.toList());
    }

}
